﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKArchMethodLibrary.Utils;
using YRevitJig;

namespace YJKDimensionModel.LevelDimension
{
	public class LevelDimensionJig : XUiJigBase
	{
		public double LineAngle { get; set; }

		public XYZ StartPoint { get; set; }

		public XYZ EndPoint { get; set; }

		public Reference EdgeReference { get; set; }

		public Element SelectedElement { get; set; }

		public LevelDimensionJig.EStage JigStage { get; set; }

		public XUiJigBase.EResetPoint ResetPoint { get; set; }

		public List<Curve> DrawCurves
		{
			get
			{
				return this.m_lstCurves;
			}
		}

		public LevelDimensionJig(UIDocument uiDoc, LevelDimensionForm dlg) : base(uiDoc)
		{
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			this.ResetPoint = XUiJigBase.EResetPoint.eNoOper;
			this.m_dlgLevelDim = dlg;
			this.m_lstCurves = new List<Curve>();
			this.m_view = uiDoc.ActiveView;
		}

		public XYZ PickStartPoint(string strPrompt = "请确定直线起点：")
		{
			try
			{
				this.JigStage = LevelDimensionJig.EStage.eStartPt;
				this.StartPoint = base.UiDoc.Selection.PickPoint(strPrompt);
			}
			catch
			{
				this.StartPoint = null;
			}
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			return this.StartPoint;
		}

		public XYZ PickEndPoint(XYZ ptStart, string strPrompt = "请确定直线终点：")
		{
			try
			{
				this.JigStage = LevelDimensionJig.EStage.eEndPt;
				this.StartPoint = ptStart;
				this.EndPoint = base.UiDoc.Selection.PickPoint(strPrompt);
				this.EndPoint = this.GetResetPoint(this.StartPoint, this.EndPoint);
			}
			catch
			{
				if (this.m_prompDlg != null && base.CmdEndType == XUiJigBase.ECmdEndType.eEnter)
				{
					base.CmdEndType = XUiJigBase.ECmdEndType.eOther;
					XYZ xyz = base.Client2Revit(this.m_ptCur);
					xyz = this.GetResetPoint(this.StartPoint, xyz);
					string inputValue = this.m_prompDlg.GetInputValue();
					double num = Common.MMToFeet(Convert.ToDouble(inputValue));
					XYZ xyz2 = (xyz - this.StartPoint).Normalize();
					this.EndPoint = this.StartPoint + xyz2 * num;
				}
				else
				{
					this.EndPoint = null;
				}
			}
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			return this.EndPoint;
		}

		public Reference PickEdge(string strPrompt = "请选择插入点：")
		{
			try
			{
				this.JigStage = LevelDimensionJig.EStage.eEdge;
				Reference edgeReference = base.UiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Edge);
				this.EdgeReference = edgeReference;
			}
			catch
			{
				this.EdgeReference = null;
			}
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			return this.EdgeReference;
		}

		public Element PickElement(string strPrompt = "请选择实体：")
		{
			try
			{
				this.JigStage = LevelDimensionJig.EStage.eElement;
				Reference reference = base.UiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
				this.StartPoint = reference.GlobalPoint;
				this.SelectedElement = base.UiDoc.Document.GetElement(reference);
			}
			catch
			{
				this.StartPoint = null;
				this.SelectedElement = null;
			}
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			return this.SelectedElement;
		}

		public Element PickElement(out Reference refer, string strPrompt = "请选择实体：")
		{
			Reference reference = null;
			try
			{
				this.JigStage = LevelDimensionJig.EStage.eElement;
				reference = base.UiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Face);
				this.StartPoint = reference.GlobalPoint;
				this.SelectedElement = base.UiDoc.Document.GetElement(reference);
			}
			catch
			{
				this.StartPoint = null;
				this.SelectedElement = null;
			}
			this.JigStage = LevelDimensionJig.EStage.eNoOper;
			refer = reference;
			return this.SelectedElement;
		}

		public XYZ GetResetPoint(XYZ ptBase, XYZ ptUser)
		{
			XYZ result = ptUser;
			if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
			{
				result = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, ptBase, this.LineAngle);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
			{
				result = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, ptBase);
			}
			else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
			{
				XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, ptBase);
				if (axisPoint != null)
				{
					result = axisPoint;
				}
			}
			return result;
		}

		public override void Draw(PaintEventArgs paintEventArgs)
		{
			base.Draw(paintEventArgs);
			if (!this.m_ptCur.IsEmpty)
			{
				if (LevelDimensionJig.EStage.eStartPt == this.JigStage)
				{
					this.DrawDimensionStyleGraph(paintEventArgs);
					return;
				}
				if (LevelDimensionJig.EStage.eEndPt == this.JigStage)
				{
					XYZ ptUser = base.Client2Revit(this.m_ptCur);
					if (this.ResetPoint == XUiJigBase.EResetPoint.eByAngle)
					{
						XYZ projectPoint = JigFuncs.GetProjectPoint(base.UiDoc, ptUser, this.StartPoint, this.LineAngle);
						this.m_ptCur = base.Revit2Client(projectPoint);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByOrtho)
					{
						XYZ orthoPoint = JigFuncs.GetOrthoPoint(base.UiDoc, ptUser, this.StartPoint);
						this.m_ptCur = base.Revit2Client(orthoPoint);
					}
					else if (this.ResetPoint == XUiJigBase.EResetPoint.eByAxis)
					{
						XYZ axisPoint = JigFuncs.GetAxisPoint(base.UiDoc, ptUser, this.StartPoint);
						if (axisPoint != null)
						{
							this.m_ptCur = base.Revit2Client(axisPoint);
							base.DrawAxisLine(paintEventArgs.Graphics, this.StartPoint, axisPoint);
						}
					}
					XGraphics g = new XGraphics(paintEventArgs.Graphics, base.JigPen);
					XLine2D xline2D = new XLine2D(base.Revit2Client(this.StartPoint), this.m_ptCur);
					xline2D.Draw(g);
					this.DrawDimensionStyleGraph(paintEventArgs);
					return;
				}
				if (LevelDimensionJig.EStage.eEdge == this.JigStage)
				{
					this.DrawDimensionStyleGraph(paintEventArgs);
					return;
				}
				if (LevelDimensionJig.EStage.eElement == this.JigStage)
				{
					this.DrawDimensionStyleGraph(paintEventArgs);
				}
			}
		}

		private List<Curve> GetDimenstionCurves(XYZ ptDimensionInsert)
		{
			List<Curve> result = new List<Curve>();
			double num = (double)this.m_view.Scale / 100.0;
			switch (this.m_dlgLevelDim.DimensionStyleGraph)
			{
			case DimensionStyle.DS_ONE:
				LevelDimensionManager.DimensionStyleGraphOne(ref result, this.m_view, ptDimensionInsert, 300.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			case DimensionStyle.DS_TWO:
				LevelDimensionManager.DimensionStyleGraphTwo(ref result, this.m_view, ptDimensionInsert, 300.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			case DimensionStyle.DS_THREE:
				LevelDimensionManager.DimensionStyleGraphThree(ref result, this.m_view, ptDimensionInsert, 300.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			case DimensionStyle.DS_FOUR:
				LevelDimensionManager.DimensionStyleGraphFour(ref result, this.m_view, ptDimensionInsert, 300.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			case DimensionStyle.DS_FIVE:
				LevelDimensionManager.DimensionStyleGraphFive(ref result, this.m_view, ptDimensionInsert, 300.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			case DimensionStyle.DS_SIX:
				LevelDimensionManager.DimensionStyleGraphSix(ref result, this.m_view, ptDimensionInsert, 100.0 * num, this.m_dlgLevelDim.HeaderStyle, false);
				break;
			}
			return result;
		}

		private void DrawDimensionStyleGraph(PaintEventArgs paintEventArgs)
		{
			this.m_lstCurves = new List<Curve>();
			this.m_lstCurves = this.GetDimenstionCurves(base.Client2Revit(this.m_ptCur));
			XGraphics g = new XGraphics(paintEventArgs.Graphics, base.JigPen);
			foreach (Curve curve in this.m_lstCurves)
			{
				if (typeof(Line) == curve.GetType())
				{
                    System.Drawing.Point ptStart = base.Revit2Client(curve.GetEndPoint(0));
                    System.Drawing.Point ptEnd = base.Revit2Client(curve.GetEndPoint(1));
					XLine2D xline2D = new XLine2D(ptStart, ptEnd);
					xline2D.Draw(g);
				}
				else if (typeof(Arc) == curve.GetType())
				{
					Arc arc = curve as Arc;
                    System.Drawing.Point ptStart2 = base.Revit2Client(curve.GetEndPoint(0));
                    System.Drawing.Point ptEnd2 = base.Revit2Client(curve.GetEndPoint(1));
                    System.Drawing.Point ptOnArc = base.Revit2Client(arc.Evaluate(0.5, true));
					XArc2D xarc2D = new XArc2D(ptStart2, ptEnd2, ptOnArc);
					xarc2D.Draw(g);
				}
			}
		}

		private LevelDimensionForm m_dlgLevelDim;

		private List<Curve> m_lstCurves;

        private Autodesk.Revit.DB.View m_view;

		public enum EStage
		{
			eNoOper,
			eStartPt,
			eEndPt,
			eEdge,
			eElement
		}
	}
}
